class_name DamageInfo
extends Resource


enum DamageAttribute
{
    NORMAL,
    FIRE,
    ICE,
    THUNDER,
}


var source: Character
var target: Character

@export var damage: float
@export var attribute: DamageAttribute
@export var critical_rate: float
@export var critical_degree: float
@export var can_miss: bool = true
@export var ignore_shield: bool
@export var ignore_defense: bool
@export var ignore_resistance: bool

## 可以被DamageSyetem处理的最大次数, 若为-1则表示会被DamageSystem重复处理，直到is_valid被设为false, 或该info被释放
@export var max_handled_count: int = 1

## 伤害（攻击）方向。 在DamageReceiver中对该字段进行赋值
var direction: Vector2 = Vector2.ZERO

#region 通过DamageSystem计算处理后在填充的字段
var calced_damage: float
var is_critical: bool
var is_miss: bool

## 被DamageSystem处理的次数，达到最大处理次数后，该info无效（is_valid=false），不会再被DamageSystem处理
var handled_count: int:
    set(value):
        handled_count = value
        if max_handled_count == -1: return
        if handled_count == max_handled_count:
            is_valid = false
#endregion

var attachment: Dictionary
var is_valid: bool = true


func setup(src: Character, tar: Character, 
            damage_: float, attr: DamageAttribute,
            critical_rate_: float, critical_degree_: float,
            can_miss_: bool, 
            ignore_shield_: bool, ignore_defense_: bool, ignore_resistance_: bool,
            max_handled_count_: int = 1) -> void:
    source = src
    target = tar
    damage = damage_
    attribute = attr
    critical_rate = critical_rate_
    critical_degree = critical_degree_
    can_miss = can_miss_
    ignore_shield = ignore_shield_
    ignore_defense = ignore_defense_
    ignore_resistance = ignore_resistance_
    max_handled_count = max_handled_count_


func copy() -> DamageInfo:
    var info := DamageInfo.create(
        source, target,
        damage, attribute,
        critical_rate, critical_degree, can_miss,
        ignore_shield, ignore_defense, ignore_resistance,
        max_handled_count
    )
    
    info.calced_damage = calced_damage
    info.is_critical = is_critical
    info.is_miss = is_miss
    info.handled_count = handled_count
    info.attachment = attachment.duplicate(true)
    info.is_valid = is_valid
    return info


func get_damage_attribute_color() -> Color:
    return get_damage_attribute_clr(attribute)


func get_damage_attribute_text() -> String:
    return get_damage_attribute_str(attribute)


func random_attribute() -> void:
    var attr_str: String = DamageAttribute.keys().pick_random()
    attribute = DamageAttribute.get(attr_str)


func get_target_attr_resistance() -> float:
    match attribute:
        DamageInfo.DamageAttribute.FIRE: return target.data.fire_resistance.value
        DamageInfo.DamageAttribute.ICE: return target.data.ice_resistance.value
        DamageInfo.DamageAttribute.THUNDER: return target.data.thunder_resistance.value
        _: return 0


static func get_damage_attribute_clr(attr_: DamageAttribute) -> Color:
    match attr_:
        DamageAttribute.FIRE: return Color8(255,69,0)
        DamageAttribute.ICE: return Color8(153,255,255)
        DamageAttribute.THUNDER: return Color.YELLOW
        _: return Color.WHITE


static func get_damage_attribute_str(attr_: DamageAttribute) -> String:
    match attr_:
        DamageAttribute.FIRE: return "火"
        DamageAttribute.ICE: return "冰"
        DamageAttribute.THUNDER: return "雷"
        _: return "无"


static func create(src: Node2D, tar: Node2D, 
            damage_: float, attr: DamageAttribute,
            critical_rate_: float, critical_degree_: float,
            can_miss_: bool, 
            ignore_shield_: bool, ignore_defense_: bool, ignore_resistance_: bool,
            max_handled_count_: int = 1) -> DamageInfo:
        var info := DamageInfo.new()
        info.setup(src, tar, damage_, attr, critical_rate_, critical_degree_, 
                    can_miss_, ignore_shield_, ignore_defense_, ignore_resistance_,
                    max_handled_count_)
        return info
